package com.topisv.tms.service.stock;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.stock.ViewCusStock;
import com.topisv.tms.repository.AreaGroupDao;
import com.topisv.tms.repository.stock.ViewCusStockDao;
import com.topisv.tms.service.base.BaseService;

/**
 * 商家库存视图_service
 * @author ch
 */
@Component
@Transactional(readOnly = true)
public class ViewCusStockService extends BaseService{
	
	@Autowired
	private ViewCusStockDao viewCusStockDao;
	@Autowired
	private AreaGroupDao areaGroupDao;
	
	public Page<ViewCusStock> loadViewStock(Map<String, Object> filterParams, int pageNumber, int pageSize) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);	
		PageRequest pageRequest = buildSkuPageRequest(pageNumber, pageSize);
		Specification<ViewCusStock> spec = DynamicSpecifications.bySearchFilter(filters.values(), ViewCusStock.class);
		Page<ViewCusStock> page=this.viewCusStockDao.findAll(spec,pageRequest);
		return page;
	}
	public Page<ViewCusStock> loadViewStockWarning(Map<String, Object> filterParams, int pageNumber, int pageSize) {
		final Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);	
		PageRequest pageRequest = buildSkuPageRequest(pageNumber, pageSize);
		Page<ViewCusStock> page=this.viewCusStockDao.findAll(new Specification<ViewCusStock>() {
			@Override
			public Predicate toPredicate(Root<ViewCusStock> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Specification<ViewCusStock> spec = DynamicSpecifications.bySearchFilter(filters.values(), ViewCusStock.class);
				Predicate predicate = spec.toPredicate(r, q, cb);
				predicate.getExpressions().add(cb.lessThan(r.<Integer>get("salesNum"),r.<Integer>get("safeNum")));
				return predicate;
			}
		},pageRequest);
		return page;
	}
	private PageRequest buildSkuPageRequest(int pageNumber, int pagzSize) {
		String[] sorts={"salesNum","sku"};
		Sort sort=new Sort(Direction.ASC,sorts);
		return new PageRequest(pageNumber - 1, pagzSize, sort);
	}
	public Page<ViewCusStock> loadViewStock(final QueryParamHolder paramHolder) {
		return findByJson(paramHolder, viewCusStockDao, new  Specification<ViewCusStock>() {
			@Override
			public Predicate toPredicate(Root<ViewCusStock> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Specification<ViewCusStock> spec = buildSpecification(paramHolder.getSearchParams(), ViewCusStock.class);
				Predicate predicate = spec.toPredicate(r, q, cb);
				
				Specification<ViewCusStock> specCus = getWhereClauseCus(paramHolder.getParamMap());
				Predicate predicateCus = specCus.toPredicate(r, q, cb);
				
				predicate.getExpressions().addAll(predicateCus.getExpressions());
				return predicate;
			}
		},ViewCusStock.class);
	}
	public Page<ViewCusStock> loadViewStockWarning(final QueryParamHolder paramHolder) {
		return findByJson(paramHolder, viewCusStockDao, new Specification<ViewCusStock>() {
			@Override
			public Predicate toPredicate(Root<ViewCusStock> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Specification<ViewCusStock> spec = buildSpecification(paramHolder.getSearchParams(), ViewCusStock.class);
				Predicate predicate = spec.toPredicate(r, q, cb);
				predicate.getExpressions().add(cb.lessThanOrEqualTo(r.<Integer>get("salesNum"),r.<Integer>get("safeNum")));
				return predicate;
			}
		}, ViewCusStock.class);
	}
	
	
	/**
	 * 分页查询库存信息
	 * @param customerCode 商家编码
	 * @param warehouseCode 仓库编码
	 * @param sku SKU编码
	 * @param pageNumber
	 * @param pageSize
	 * @ mh 模糊查询标志
	 * @return
	 */
	public Page<ViewCusStock> loadViewStock(String customerCode, String warehouseCode, String val, String flag, int pageNumber, int pageSize) {
		return loadViewStock(customerCode,warehouseCode,val,flag,pageNumber,pageSize,true);
	}
	public Page<ViewCusStock> loadViewStock(String customerCode, String warehouseCode, String val, String flag, int pageNumber, int pageSize,boolean mh) {
		Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
		
		if(null!=customerCode && !"".equals(customerCode)){
			filters.put("customerCode", new SearchFilter("customer.customerCode", Operator.EQ, customerCode));
		}
		if(null!=warehouseCode && !"".equals(warehouseCode)){
			filters.put("warehouseCode", new SearchFilter("warehouseCode", Operator.EQ, warehouseCode));
		}
		
		
		if(null!=val && !"".equals(val)){
			
			if(flag.equals("sku")){
				if(mh){
					filters.put("sku", new SearchFilter("sku", Operator.LIKE, "%"+val+"%"));
				} else {
					filters.put("sku", new SearchFilter("sku", Operator.EQ, val));
				}
			}else if(flag.equals("bar")){
				if(mh){
					filters.put("bar", new SearchFilter("bar", Operator.LIKE, "%"+val+"%"));
				} else {
					filters.put("bar", new SearchFilter("bar", Operator.EQ, val));
				}
			}else if(flag.equals("name")){
				if(mh){
					filters.put("name", new SearchFilter("goodsName", Operator.LIKE, "%"+val+"%"));
				} else {
					filters.put("name", new SearchFilter("goodsName", Operator.EQ, val));
				}
			}
			
			
		}
		
		
		
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize);
		Specification<ViewCusStock> spec = DynamicSpecifications.bySearchFilter(filters.values(), ViewCusStock.class);
		Page<ViewCusStock> page=this.viewCusStockDao.findAll(spec,pageRequest);
		
	    List<ViewCusStock> list=page.getContent();
	    
	    for (ViewCusStock viewCusStock : list) {
			String _warehouseCode=viewCusStock.getWarehouseCode();
			AreaGroup warehouse=this.areaGroupDao.findByGroupCode(_warehouseCode);
			viewCusStock.setWarehouse(warehouse);
		}
		
		return page;
	}
	
	
	private PageRequest buildPageRequest(int pageNumber, int pagzSize) {
		String[] sorts={"customer.customerCode","warehouseCode","sku"};
		Sort sort=new Sort(Direction.ASC,sorts);
		return new PageRequest(pageNumber - 1, pagzSize, sort);
	}


	/**
	 * 查询
	 * @param customerCode
	 * @param areagroupCode
	 * @param sku
	 * @return
	 */
	public ViewCusStock loadByCondition(String customerCode,String warehouseCode,String sku) {
		return this.viewCusStockDao.loadStockByCondition(customerCode,warehouseCode,sku);
	}
	
	public List<ViewCusStock> findStockByCondition(String customerCode,String warehouseCode, String code){
		return this.viewCusStockDao.findStockByCondition(customerCode, warehouseCode, code);
	}
	
	
	/**
	 * 查询
	 * @param param
	 * @return
	 */
	public List<ViewCusStock> loadByParam(Map<String, Object> param) {
		Sort sort = new Sort(Sort.Direction.ASC,"id");
	    Specification<ViewCusStock> spec =this.getWhereClause(param);
	    List<ViewCusStock> list = this.viewCusStockDao.findAll(spec, sort);
	    for (ViewCusStock viewCusStock : list) {
			this.setDetail(viewCusStock);
		}
	    return list;
	}
	
	/**
	 * 设置属性
	 * @param viewCusStock
	 */
	public void setDetail(ViewCusStock viewCusStock) {
		
		//warehouse
		String warehouseCode=viewCusStock.getWarehouseCode();
		AreaGroup warehouse=this.areaGroupDao.findByGroupCode(warehouseCode);
		viewCusStock.setWarehouse(warehouse);
		
	}


	/**
	 * 条件封装
	 * @param params
	 * @return
	 */
	private Specification<ViewCusStock> getWhereClause(final Map<String, Object> params) {
		 return new Specification<ViewCusStock>(){
		    @Override
		    public Predicate toPredicate(Root<ViewCusStock> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
		      Predicate pre = cb.conjunction();
		      
		      //customerCode
		      String customerCodes=(String) params.get("customerCode");
		      if(StringUtils.isNotBlank(customerCodes)){
		    	  String[] customerCodeSplit = customerCodes.split(":");
				  ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
				  int i = 0;
				  for (String _customerCode : customerCodeSplit) {
					 tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customer").get("customerCode"), _customerCode);
					 i++;
				  }
				  pre.getExpressions().add(cb.or(tempCustomerCode));
		    	 // pre.getExpressions().add(cb.equal(r.get("customer").get("customerCode"),customerCode));
		      }
			  
		      //warehouseCode
		      String warehouseCode=(String) params.get("warehouseCode");
		      if(StringUtils.isNotBlank(warehouseCode)){
		    	  pre.getExpressions().add(cb.equal(r.get("warehouseCode"),warehouseCode));
		      }
		      
		      //sku
		      String sku=(String) params.get("sku");
		      if(StringUtils.isNotBlank(sku)){
		    	  pre.getExpressions().add(cb.like(r.<String>get("sku"), "%"+sku+"%"));
			  }
		      
		     //bar
		     String bar=(String) params.get("bar");
		     if(StringUtils.isNotBlank(bar)){
		        pre.getExpressions().add(cb.like(r.<String>get("bar"), "%"+bar+"%"));
			 }
		     
		     //name
		     String name=(String) params.get("name");
		     if(StringUtils.isNotBlank(name)){
		        pre.getExpressions().add(cb.like(r.<String>get("goodsName"), "%"+name+"%"));
			 }
		      
		      return pre;
		    }
		  };
	}

	/**
	 * 条件封装
	 * @param params
	 * @return
	 */
	private Specification<ViewCusStock> getWhereClauseCus(final Map<String, String> params) {
		 return new Specification<ViewCusStock>(){
		    @Override
		    public Predicate toPredicate(Root<ViewCusStock> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
		      Predicate pre = cb.conjunction();
		    //customerCodes
		      String customerCodes=(String) params.get("customerCodes");
		      if(StringUtils.isNotBlank(customerCodes)) {
		    	  String[] customerCodeSplit = customerCodes.split(":");
				  ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
				  int i = 0;
				  for (String _customerCode : customerCodeSplit) {
					 tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customer").get("customerCode"), _customerCode);
					 i++;
				  }
				  pre.getExpressions().add(cb.or(tempCustomerCode));
		      }
		      //areagroups
		      String areagroups=(String) params.get("areagroups");
		      if(StringUtils.isNotBlank(areagroups)) {
		    	  String[] areagroupSplit = areagroups.split(":");
				  ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
				  int j = 0;
				  for (String _areagroup : areagroupSplit) {
						areagroupArray[j] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), _areagroup);
						j++;
				  }
				  pre.getExpressions().add(cb.or(areagroupArray));
			  }
		      return pre;
		    }
		  };
	}
	
    /**
     * SQL查询库存
     * add 20160601 lianghe.yuan
     * @param customerCode 客户编码
     * @param warehouseCode 仓库编码
     * @param sku SKU编码
     * @return 数组集合
     */
    public List<Object[]> exportStockBySku(List<String> customerCodes, String warehouseCode, String sku) {
        if (StringUtils.isNotBlank(sku)) {
            sku = "%" + sku + "%";
        }
        return this.viewCusStockDao.exportStockBySku(customerCodes, warehouseCode, sku);
    }
    
}
